package starComponent.elements;

import java.awt.Color;
import java.awt.Rectangle;

import starComponent.E_PossibleBranches;

/**
 * @author Charles Perin
 * 11 avr. 2011
 * LIMSI - INRIA Rennes
 * charles.perin@free.fr
 */
public class StarBranchCircular extends A_StarBranch{

	private static final long serialVersionUID = -6622621084774458091L;

	private Thumb thumb;
	
	private double circleRadius, circleCenter, xCircleCenter, yCircleCenter;

	/**
	 * Branche "Slider"
	 * @param star le starComponent associe
	 * @param name le nom de la branche
	 * @param min valeur min
	 * @param max valeur max
	 * @param value valeur par defaut
	 * @param color la couleur de la branche
	 * @param ladder l'echelle de valeurs
	 * @param angle l'angle de la branche : [0;2PI]
	 */
	public StarBranchCircular(StarComponent star, E_PossibleBranches branch, Color color, Ladder ladder, double angle, boolean isDisplayed) {
		super(star, branch, color, ladder, angle, isDisplayed);
		if(branch.getType()==E_PossibleBranches.QUANTITATIVE_SLIDER || branch.getType()==E_PossibleBranches.QUALITATIVE_SLIDER){
			this.thumb = new Thumb(this);
			thumb.setValue(branch.getStartValue());
		}
		else System.err.println("StarBranchCircular: erreur a la creation de "+branch.getName());
	}
	
	@Override
	public void updateBranch(){
		double internCircleRadius = star.getControler().getInternCircleRadius();
		double externCircleRadius = star.getControler().getExternCircleRadius();
		double xMiddle = star.getWidth()/2;
		double yMiddle = star.getHeight()/2;
		xStart = internCircleRadius*Math.cos(angle)+xMiddle;
		yStart = -internCircleRadius*Math.sin(angle)+yMiddle;
		xEnd = externCircleRadius*Math.cos(angle)+xMiddle;
		yEnd = -externCircleRadius*Math.sin(angle)+yMiddle;
		length = Math.sqrt(Math.pow(Math.abs(xStart-xEnd),2)+Math.pow(Math.abs(yStart-yEnd),2));
		middle.setLocation((xEnd-xStart)/2, (yEnd-yStart)/2);
		ladder.updateLadderMap(this);
		buildBoundingBox();

		//TODO init de circleRadius et circleCenter et xCircle, yCircle
		
		this.getThumb().initPosition();
		this.getFlyingNameLabel().updateText();
		
	}
	
	@Override
	protected void buildBoundingBox(){//TODO - afficher les rect pour test
		
		double x0,y0,x1,y1;
		x0 =  star.getCenter().getX();
		x1 =  xEnd;
		y0 =  star.getCenter().getY();
		y1 =  yEnd;

		double y0Backup=y0;
		double x0Backup=x0;
		
		boolean leftToRight = xStart<=xEnd;
		boolean downToTop = yStart<=yEnd;
		
		//Si construction par rectangles horizontaux
		if(angle>Math.PI/4 && angle<3*Math.PI/4){
			if(leftToRight){
				while(x0<=x1+BOUNDING_MARGIN && y0>=y1-BOUNDING_MARGIN){
					Rectangle r = new Rectangle((int)(x0-BOUNDING_SIDE/2), (int)y0, BOUNDING_SIDE, BOUNDING_STEP);
					x0 = (int) (-(y0-y0Backup)/Math.tan(angle)+x0Backup);
					y0 -= BOUNDING_STEP;
	
					boundingList.add(r);
				}
			}
			else{
				while(x0>=x1-BOUNDING_MARGIN && y0>=y1-BOUNDING_MARGIN){
					Rectangle r = new Rectangle((int)(x0-BOUNDING_SIDE/2), (int)y0, BOUNDING_SIDE, BOUNDING_STEP);
					x0 = (int) (-(y0-y0Backup)/Math.tan(angle)+x0Backup);
					y0 -= BOUNDING_STEP;
	
					boundingList.add(r);
				}
			}
		}
		else if(angle >5*Math.PI/4 && angle < 7*Math.PI/4){
			if(leftToRight){
				while(x0<=x1+BOUNDING_MARGIN && y0<=y1+BOUNDING_MARGIN){
					Rectangle r = new Rectangle((int)(x0-BOUNDING_SIDE/2), (int)y0, BOUNDING_SIDE, BOUNDING_STEP);
					x0 = (int) (-(y0-y0Backup)/Math.tan(angle)+x0Backup);
					y0 += BOUNDING_STEP;
	
					boundingList.add(r);
				}
			}
			else{
				while(x0>=x1-BOUNDING_MARGIN && y0<=y1+BOUNDING_MARGIN){
					Rectangle r = new Rectangle((int)(x0-BOUNDING_SIDE/2), (int)y0, BOUNDING_SIDE, BOUNDING_STEP);
					x0 = (int) (-(y0-y0Backup)/Math.tan(angle)+x0Backup);
					y0 += BOUNDING_STEP;
	
					boundingList.add(r);
				}
			}
		}
		//si construction par rectangles verticaux
		else{
			if(leftToRight){
				if(downToTop){
					while(x0<=x1+BOUNDING_MARGIN && y0<=y1+BOUNDING_MARGIN){
						Rectangle r = new Rectangle((int)x0, (int)(y0-BOUNDING_SIDE/2), BOUNDING_STEP, BOUNDING_SIDE);
						x0+=BOUNDING_STEP;
						y0 = (-(x0-xStart)*Math.tan(angle)+yStart);

						boundingList.add(r);
					}
				}
				else{
					while(x0<=x1+BOUNDING_MARGIN && y0>=y1-BOUNDING_MARGIN){
						Rectangle r = new Rectangle((int)x0, (int)(y0-BOUNDING_SIDE/2), BOUNDING_STEP, BOUNDING_SIDE);
						x0+=BOUNDING_STEP;
						y0 = (-(x0-xStart)*Math.tan(angle)+yStart);

						boundingList.add(r);
					}
				}
				
			}
			else{
				if(downToTop){
					while(x0>=x1-BOUNDING_MARGIN && y0<=y1+BOUNDING_MARGIN){
						Rectangle r = new Rectangle((int)x0, (int)(y0-BOUNDING_SIDE/2), BOUNDING_STEP, BOUNDING_SIDE);
						x0-=BOUNDING_STEP;
						y0 = (-(x0-xStart)*Math.tan(angle)+yStart);

						boundingList.add(r);
					}
				}
				else{
					while(x0>=x1-BOUNDING_MARGIN && y0>=y1-BOUNDING_MARGIN){
						Rectangle r = new Rectangle((int)x0, (int)(y0-BOUNDING_SIDE/2), BOUNDING_STEP, BOUNDING_SIDE);
						x0-=BOUNDING_STEP;
						y0 = (-(x0-xStart)*Math.tan(angle)+yStart);

						boundingList.add(r);
					}
				}
			}
		}
	}

	@Override
	public String toString(){
		return this.getName();
	}


	/**
	 * parametrise le thumb
	 * @param normalColor les 2 couleurs composant la couleur du thumb au repos
	 * @param selectedColor les 2 couleurs composant la couleur du thumb quand selectionne
	 */
	public void setThumbColors(Color[]normalColor,Color[]selectedColor){
		thumb.setThumbColor(normalColor);
		thumb.setThumbSelectedColor(selectedColor);
	}

	public void setValue(double value) {
		thumb.setValue(value);
	}

	public double getValue() {
		return thumb.getValue();
	}

	public void setThumb(Thumb thumb) {
		this.thumb = thumb;
	}

	public Thumb getThumb() {
		return thumb;
	}

	public void setCircleRadius(double circleRadius) {
		this.circleRadius = circleRadius;
	}

	public double getCircleRadius() {
		return circleRadius;
	}

	public void setCircleCenter(double circleCenter) {
		this.circleCenter = circleCenter;
	}

	public double getCircleCenter() {
		return circleCenter;
	}

	public void setxCircleCenter(double xCircleCenter) {
		this.xCircleCenter = xCircleCenter;
	}

	public double getxCircleCenter() {
		return xCircleCenter;
	}

	public void setyCircleCenter(double yCircleCenter) {
		this.yCircleCenter = yCircleCenter;
	}

	public double getyCircleCenter() {
		return yCircleCenter;
	}

}
